设a, b, c是3个塔座:开始时,塔座a上有n个自上而下、由小到大地叠在一起圆盘,各圆盘从小到大编号为1, 2, …, n,现要求将塔座a上的这一叠圆盘移到塔座b上,并仍按同样顺序叠置,移动圆盘时遵守以下移动规则:
规则1:每次只能移动1个圆盘;
规则2:不允许将较大的圆盘压在较小的圆盘之上;
规则3:在满足移动规则1和2的前提下,可将圆盘移至a, b, c中任一塔座上。
算法设计思路
由于移动规则为大的在下,下的在上,所以可以采用捆绑的思想来移动圆盘。具体是:起始塔座为a,目标塔座是b,所以首先借助b塔座,把前面n-1个圆盘移动到c塔座,剩下第n个圆盘则移动b塔座,最后再借助a塔座,把n-1个圆盘移动到b塔座上。
算法实现的伪代码
说明:functionA为自定义的函数名,input 1, input 2, …, input n为functionA的输入形参;在“输入”中描述各输入形参的含义;在“输出”中描述functionA的输出或作用效果;在S1~Sk中采用伪代码描述语言简要表达functionA的核心步骤。
算法functionA(input 1, input 2, …, input n)
输入:起始塔座a,目标塔座b,中介塔座c,以及圆盘的个数。
输出:圆盘实现从a塔座到塔座b的具体路径。
S1:'A'→a; 'B'→b;'C'→c; n→n;
S2:void han(a,b,c,n)
S3:if n=1 then move(a,b)
S4:else then han(a,b,c,n-1)
S5:move(a,b)
S6:han(c,a,b,n-1)
实现代码
说明:只粘贴functionA的Java或C++实现代码即可,并对算法实现的关键性语句进行注释。
public void han(char a,char c,char b,int n){
if(n==1){//边界条件
move(a,b);//当n=1时,直接移到目标塔座即可。
}
else{
han(a,b,c,n-1);//采用捆绑的方法,把上面n-1个圆盘从a塔移动到c塔
move(a,b);//把剩下的最后一个圆盘移动到b塔座
han(c,a,b,n-1);//采用捆绑法,把c塔座上的n-1个圆盘移到b塔座
}
}
算法运行结果及计算时间复杂度分析
说明:通过计算迭代次数、基本运算语句的频度,或利用递推关系估算functionA的计算时间复杂度,要求给出具体的算法分析思路与过程,不能仅列出一个结果。
具体运算过程:
由递推可算出:
T(n)=2T(n-1)+1;
T(n-1)=2T(n-2)+1;
.....
T(2)=2T(1)+1;
根据观察可以发现,右边式子中的T函数与下一式左边的式子存在着2倍的关系,所以每个式子两边同时乘以2^(n-1),得:
T(n)=2T(n-1)+1;
2*T(n-1)=2*2T(n-2)+2*1;
.....
2^(n-1)*T(2)=2^(n-1)*2T(1)+2^(n-1)*1;
所有式子相加,可得:
T(n)=2^(n-1)*2T(1)+1*(1+2+2^2+……+2^(n-1))
=2^n+2^n-1
=2^(n+1)-1
所以O(n)=O(T(n))=O(O(1)+O(2^(n+1)-1))=O(2^(n+1)+1-1)=O(2^(n+1))=O(2^n).
运行结果:
该文为原创,有什么错误的地方,可以在评论区留言。